Python语言基础

Python 语言基础

8.4 序列解包和链式赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
a = 1 
b = 2
c = 3

a,b,c = 1,2,3

# 序列解包
d = 1,2,3
a,b,c = d
print(type(d))

# 链式赋值
a=b=c=1

8.5必须参数和关键字参数

参数类型

1
2
3
4
5
6
7
8
9
10
def add(x,y):
# x,y 是形式参数 简称形参
res = x + y
print("x是%d" % x)
return res

c = add(1,2)
# 1,2 是实际参数 简称实参

c = add(y=3,x=1)
  • 必须参数

    参数必须传递,不传递会报错,在不指明关键字时必须按顺序传递

  • 关键字参数

    明确指定将哪个实参赋值给哪个形参,实现参数不按顺序传递

  • 默认参数

    指定函数不传递参数时采用的值,设置了默认值的参数在调用时可以不用传递,非默认参数不能位于默认参数之后

  • 可变参数

    使用*定义,传入函数的是一个tuple可变参数需要定义在必须参数之后,可变参数之后可以跟随默认参数,也可以在默认参数之后,但是可变参数之后的默认参数必须使用关键字形式调用,可变参数一般需要使用for循环遍历

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    def demo2(param1,param2=1,*param3):
    print(param1)
    print(param2)
    print(param3)


    def demo3(param1,*param3,param2=1):
    print(param1)
    print(param2)
    print(param3)

    demo2(1,2,3,4,5)
    demo2(1,2,3,4)

    demo3(1,2,3,4,5)
    demo3(1,2,3,4)
  • 关键字可变参数

    使用** 定义,传入函数是一个dist

8.6 变量的作用域

函数外部定义的变量作用域覆盖整个模块(全局变量),可以在函数内部使用,函数内部定义的只覆盖函数内部(局部变量) 局部是相对概念,相对于外部是局部变量 相对于内部还是全局变量

python for循环没有块级作用域

作用域链

在函数内部定义全局变量

1
2
3
4
5
6
7
8
9
def demo():
global c
c = 2

# 注意 函数内定义的全局变量需要执行函数后才生效
demo()
print(c)

# 不能使用 global c = 2的形式定义

面向对象

类是现实世界或四维世界中的实体在计算机中的反映

它将数据及这些数据上的操作封装在一起(特征+行为)

行为必须是以类为主体

python 使用class 定义类

直接使用类名加括号实例化一个类 不需要使用new操作符

类中所有方法第一个参数必须是self

定义类的模块尽量只定义而不去调用

构造函数,实例化的时候定义的时候自动执行,不能返回None之外的值,构造函数用于初始化对象的属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class <类名>:
# 定义类变量
<变量名> = <变量值>
# 定义构造函数
def __init__(self):
# 定义实例变量
self.<变量名> = <变量值>
# 定义私有实例变量
self.__<变量名> = "私有实例变量"
pass

# 定义实例方法 self 代表当前对象
def <实例方法名>(self):
pass

# 定义类方法 核心是@classmethod cls 代表当前类
@classmethod
def clsmethod(cls):
print("---这是一个类方法---")

# 类方法中访问类变量
print(cls.name)



# 定义静态方法 不需要使用self或者
@staticmethod
def <静态方法名>():
print("这是一个静态方法")

# 静态方法访问类变量
print(__class__.name)

# 定义私有方法
def __<私有方法名>():
pass

# 注意 : __<方法名>__ 形式方法名 不是私有方法
# 定义私有类变量
__name = "私有类变量"


student = Student()

# print(student.__privatevar)
student.__privatevar = "我为什么不会报错"
print(student.__privatevar)
print(student._Student__privatevar)
print(student.__dict__)
# 这个变量并没有被赋值到实例内部的私有变量中,而是添加了一个__privatevar变量
# python 保护私有变量的方式就是将私有变量的名称由__privatevar形式修改为_Student__privatevar形式
  • 变量

    • 类变量

      类变量使用<类名>.<变量名>访问

      类变量还可以使用self.__class__的方式访问

      类中方法引用类变量需要使用self.操作符

    • 实例变量

      实例化时传入的变量

      实例变量保存在self中,如果没有使用没有定义的实例变量时,会在类变量中进行寻找

      self当前调用方法的对象

  • 方法

    • 实例方法

      类的实例可以使用的方法

    • 类方法

      将类本身作为对象进行操作的方法。类方法使用@classmethod装饰器定义,第一个参数是类,约定写为cls。类对象和实例都可以调用类方法

    • 静态方法

      是一种普通函数,位于类的命名空间中,它不能对任何实例类型进行操作,使用装饰器@staticmethod定义静态方法。类对象和实例都可以调用静态方法。

  • 成员可见性

    类有内外之分,变量的修改应该使用方法进行操作 而不是直接修改变量

    • 公开public

      python默认定义的成员都是公开的

    • 私有 private

      如果对变量或者方法名前加双下划线,定义的成员是私有的

  • 面向对象三大特性

    • 继承

      父类:

      1
      2
      3
      # 父类子类在同一文件夹 
      # 父类文件名为 c1.py
      class FatherClass():
  • 封装

  • 多态

    开闭原则 开放扩展 封闭修改

本节中,在类外面调用类变量时使用<类名.类变量名>的形式调用,那么在类内部如何随时调用类变量呢?

在类外部引用实例变量时,使用<实例化后的类名>.<变量名>形式来引用,当不存在这个实例变量时,会在类变量中去寻找,同样在类的内部引实例变量时,可以使用self.<变量名>的形式引用,如果不存在该实例变量,会在类变量中寻找,那么当已经定义了一个和类变量同名的实例变量后,该如何在次访问类变量呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 定义一个类
class Student():
# 定义类变量
name = "类变量值"

# 定义构造函数
def __init__(self,name="实例变量值"):
print(self.name) # 打印出类变量
# 定义实例变量
self.name = name
print(self.name) # 打印出实例变量
print(name) # 打印出实例变量

# 问题 此时 该如何访问类变量name呢?
print("通过类名访问",Student.name) # 打印出类变量
print("通过self.__class__访问",self.__class__.name)

###